
package com.gcloud.mesh.dcs.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Repository;

import com.gcloud.framework.db.PageResult;
import com.gcloud.framework.db.dao.impl.JdbcBaseDaoImpl;
import com.gcloud.mesh.dcs.entity.ModelScoreEntity;
import com.gcloud.mesh.header.enums.ModelType;
import com.gcloud.mesh.header.vo.dcs.BestScoreDatacenter;
import com.gcloud.mesh.header.vo.dcs.PageModelScoreVo;
import com.gcloud.mesh.header.vo.dcs.SchedulerJobVo;

import io.micrometer.core.instrument.util.StringUtils;

@Repository
public class ModelScoreDao extends JdbcBaseDaoImpl<ModelScoreEntity, String> {

    /*    public <E> List<E> get(ModelType modelType, String resourceId, Class<E> clazz) {
        Map<String, Object> props = new HashMap<>();
        props.put("modelType", modelType.name());
        props.put("resourceId", resourceId);
        return this.findByProperties(props, "factorId", "ASC", clazz);
    }*/

    public <E> E get(ModelType modelType, String resourceId, Class<E> clazz) {
        Map<String, Object> props = new HashMap<>();
        props.put("modelType", modelType.name());
        props.put("resourceId", resourceId);
        return this.findUniqueByProperties(props, clazz);
    }
    
    public <E> List<E> getPageOrderByTime(ModelType modelType, String resourceId, Class<E> clazz){
    	List<Object> values = new ArrayList<>();
    	
    	StringBuilder sb = new StringBuilder();
    	sb.append("SELECT d.* FROM dcs_model_scores d  WHERE 1=1 ");

		if (modelType.name() != null) {
			sb.append(" AND d.model_type = ? ");
			values.add(modelType.name());
		}
		if (resourceId != null) {
			sb.append(" AND d.resource_id = ?");
			values.add(resourceId);
		}
		sb.append(" ORDER BY d.update_time DESC");
		
		return this.findBySql(sb.toString(), values, clazz);
    }

    public <E> PageResult<E> getPage4Migration(String spType, ModelType modelType, Integer pageNo, Integer pageSize, String deviceName, String datacenterId, Class<E> clazz){
        StringBuilder sql=new StringBuilder();
        List<Object> values=new ArrayList<>();
        sql.append("SELECT a.id,a.name,a.datacenter_id,d.resource_id,d.scores,d.factor_names,d.total_score,d.samples FROM asset_iaas a " +
                " inner join supplier_suppliers sp on sp.datacenter_id = a.datacenter_id " +
                " LEFT JOIN dcs_model_scores d ON a.id=d.resource_id WHERE 1=1");
        sql.append(" AND d.model_type=?");
        values.add(modelType.name());
        if (StringUtils.isNotEmpty(datacenterId)){
            sql.append(" AND sp.datacenter_id=?");
            values.add(datacenterId);
        }
        if (StringUtils.isNotEmpty(spType)){
            sql.append(" AND sp.type=? ");
            values.add(spType);
        }
        if ((StringUtils.isNotEmpty(deviceName))){
            sql.append(" AND name like concat('%',?,'%')");
            values.add(deviceName);
        }
        sql.append(" AND update_time in (select max(update_time) from dcs_model_scores where model_type = ?)");
        values.add(modelType.name());

        sql.append(" GROUP BY a.id ORDER BY d.total_score DESC");

        return this.findBySql(sql.toString(),values,pageNo, pageSize, clazz);
    }

    public <E> PageResult<E> getPage(ModelType modelType,Integer pageNo,Integer pageSize,String deviceName,String datacenterId, Class<E> clazz){
        StringBuilder sql=new StringBuilder();
        List<Object> values=new ArrayList<>();
        
        if(modelType.getDeviceType() == 8 || modelType.getDeviceType() == 3){
        	sql.append("SELECT a.id,a.name,a.cloud_resource_id,acr.datacenter_id,dc.name as datacenterName, d.values,  d.resource_id,d.scores,d.factor_names,d.total_score,d.samples FROM dcs_apps a LEFT JOIN dcs_model_scores d ON a.id=d.resource_id left join asset_cloud_resources acr on a.cloud_resource_id = acr.id left join asset_datacenters dc on acr.datacenter_id = dc.id WHERE 1=1");
        }else if(modelType.getDeviceType() == 6){
        	sql.append("SELECT a.id,a.name,a.datacenter_id,dc.name as datacenterName, d.values, d.resource_id,d.scores,d.factor_names,d.total_score,d.samples FROM asset_iaas a LEFT JOIN dcs_model_scores d ON a.id=d.resource_id left join asset_datacenters dc on a.datacenter_id = dc.id WHERE 1=1");
        }else{
        	sql.append("SELECT a.id,a.name,a.name as datacenterName, a.id as datacenter_id, d.values, d.resource_id,d.scores,d.factor_names,d.total_score,d.samples FROM asset_datacenters a LEFT JOIN dcs_model_scores d ON a.id=d.resource_id WHERE 1=1");
        }
        sql.append(" AND d.model_type=?");
        values.add(modelType.name());
        if (StringUtils.isNotEmpty(datacenterId)){
        	if(modelType.getDeviceType() == 1 || modelType.getDeviceType() == 2){
        		sql.append(" AND a.id=?");
        	}else if(modelType.getDeviceType() == 6){
        		sql.append(" AND a.datacenter_id=?");
        	}else if(modelType.getDeviceType() == 8 || modelType.getDeviceType() == 3){
        		sql.append(" AND acr.datacenter_id=?");
        	}else {
        		sql.append(" AND a.id=?");
        	}
            values.add(datacenterId);
        }
        if ((StringUtils.isNotEmpty(deviceName))){
            sql.append(" AND a.name like concat('%',?,'%')");
            values.add(deviceName);
        }
        sql.append(" AND update_time in (select max(update_time) from dcs_model_scores where model_type = ?)");
        values.add(modelType.name());
        
        sql.append(" GROUP BY a.id ORDER BY d.total_score DESC");

        return this.findBySql(sql.toString(),values,pageNo, pageSize, clazz);
    }
    
    public void deleteByDate(String date) {
		StringBuffer sql = new StringBuffer();
		sql.append("delete from dcs_model_scores where update_time <= ? ");	
		this.jdbcTemplate.update(sql.toString(), date);
    }
    
    public String getBestScoreCenter(ModelType modelType, String datacenterIds) {
    	 StringBuilder sql=new StringBuilder();
         List<Object> values=new ArrayList<>();
         
         if(modelType.getDeviceType() == 3){
         	sql.append("SELECT a.id as datacenterId FROM dcs_apps a LEFT JOIN dcs_model_scores d ON a.id=d.resource_id WHERE 1=1");
         }else{
         	sql.append("SELECT a.id as datacenterId FROM asset_datacenters a LEFT JOIN dcs_model_scores d ON a.id=d.resource_id WHERE 1=1");
         }
         sql.append(" AND d.model_type=?");
         values.add(modelType.name());

         if(StringUtils.isNotBlank(datacenterIds)) {
         	sql.append(" AND a.id in ("+datacenterIds+") ");
         }
         sql.append(" AND update_time in (select max(update_time) from dcs_model_scores where model_type = ?)");
         values.add(modelType.name());
         
         sql.append(" GROUP BY a.id ORDER BY d.total_score DESC");

         List<BestScoreDatacenter> datacenters = this.findBySql(sql.toString(),values,BestScoreDatacenter.class);
         if(datacenters !=null && !datacenters.isEmpty()) {
        	 return datacenters.get(0).getDatacenterId();
         }
         return null;
    }

    /*    public void updateBatch(ModelScoreEntity[] scores) {
        String sql = "UPDATE dcs_model_factors SET enabled = ?, score_sample = ?, score_type = ?, weight = ? WHERE id = ?";
        this.jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
    
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                ps.setBoolean(1, scores[i].getEnabled());
                ps.setInt(2, scores[i].getScoreSample());
                ps.setString(3, scores[i].getScoreType());
                ps.setInt(4, scores[i].getWeight());
                ps.setString(5, scores[i].getId());
            }
    
            @Override
            public int getBatchSize() {
                return scores.length;
            }
        });
    }*/
	public Map<String, Integer> getAppScore(){
		StringBuffer buffer = new StringBuffer();
		buffer.append("select a.id as resource_id, b.total_score, b.update_time from dcs_apps a ,(SELECT d.* FROM dcs_model_scores d  WHERE 1=1 and model_type = 'APP' ORDER BY update_time) b where a.id = b.resource_id GROUP BY a.id");
		List<ModelScoreEntity> entitys = findBySql(buffer.toString());
		Map<String, Integer> scores = new HashMap<>();
		for(ModelScoreEntity entity : entitys) {
			scores.put(entity.getResourceId(), entity.getTotalScore());
		}
		return scores;
	}
    

}
